package com.youcan.search;




import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrResourceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

/**
 * SolrServer的包装器，提供Solr的嵌入式启动方法，以及关闭，获取solr core对应的SolrServer。
 * 
 */
public class SolrServerWrapper {

	private static final Logger logger = LoggerFactory
			.getLogger(SolrServerWrapper.class);

	private static CoreContainer container;
	private static String searchServerHome;

	/**
	 * @throws ParserConfigurationException
	 * @throws IOException
	 * @throws SAXException
	 */
	private SolrServerWrapper() {

	}

	/**
	 * @param productHome
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws ParserConfigurationException
	 * @throws IOException
	 * @throws SAXException
	 */
	public static CoreContainer initContainer(String productHome)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, SecurityException,
			NoSuchMethodException, ParserConfigurationException, IOException,
			SAXException {
		URLClassLoader classloader = (URLClassLoader) ClassLoader
				.getSystemClassLoader();
		Method addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL",
				URL.class);
		addURLMethod.setAccessible(true);
		URL url = new URL("file:///" + productHome);
		addURLMethod.invoke(classloader, url);
		
		String solrHome = SolrResourceLoader.locateSolrHome();
		if (new File(solrHome).isAbsolute() == false) {
			solrHome = productHome
					+ (solrHome.startsWith("/") || solrHome.startsWith("\\") ? solrHome
							.substring(1) : solrHome);
		}
		File f = new File(solrHome, "solr.xml");
		container = new CoreContainer(new SolrResourceLoader(solrHome));
		container.load(solrHome, f);
		container.setPersistent(false);
		logger.info("Solr module initialization complete！");
		setSearchServerHome(solrHome);
		
		return container;
	}

	/**
	 * 关闭Solr 引擎。
	 * 
	 * @throws SolrException
	 */
	public void shutdown() throws SolrException {
		if (container == null) {
			throw new SolrException("Cannot close solr module!!!");
		}
		if (container.isPersistent()) {
			container.persist();
		}
		container.shutdown();
		logger.info("Solr module closed!");
	}

	/**
	 * 将Solr配置持久化。
	 * 
	 * @throws SolrException
	 */
	public synchronized void persist() throws SolrException {
		if (container == null) {
			throw new SolrException("Cannot persist solr module.");
		}
		container.persist();
		logger.info("Solr module persist compelete.");
	}

	/**
	 * 添加一个solr core。
	 * 
	 * @param solrName
	 *            core的名称
	 * @param instanceDir
	 *            所在目录
	 * @param isPersist
	 *            是否需要持久化
	 * @throws ParserConfigurationException
	 * @throws IOException
	 * @throws SAXException
	 */
	public synchronized void addCore(String solrName, String instanceDir,
			boolean isPersist) throws ParserConfigurationException,
			IOException, SAXException {
		CoreDescriptor p = new CoreDescriptor(container, solrName, instanceDir);
		SolrCore core = container.create(p);
		container.register(solrName, core, false);
		if (isPersist) {
			container.persist();
		}
	}

	/**
	 * 根据solr core名获取相应的SolrServer实例。
	 * 
	 * @param solrName
	 * @return SolrServer实例。
	 */
	public static SolrServer getSolrServer(String solrName) {
		if (container.getCoreNames().contains(solrName)) {
			return new EmbeddedSolrServer(container, solrName);
		}
		return null;
	}

	/**
	 * 根据solr core名获取SolrCore实例。
	 * 
	 * @param coreName
	 * @return solrCore实例。
	 */
	public static SolrCore getSolrCore(String coreName) {
		if (container.getCoreNames().contains(coreName)) {
			return container.getCore(coreName);
		}
		return null;
	}

	public static CoreContainer getContainer() {
		return container;
	}

	public String getSearchServerHome() {
		return searchServerHome;
	}

	public static void setSearchServerHome(String searchServerHome) {
		SolrServerWrapper.searchServerHome = searchServerHome;
	}
}